<template>
  <div class="profile-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>个人中心</span>
        </div>
      </template>

      <el-tabs v-model="activeTab" type="border-card" @tab-change="handleTabChange">
        <!-- 基本信息 -->
        <el-tab-pane label="基本信息" name="info">
          <el-form
            ref="infoFormRef"
            :model="infoForm"
            :rules="infoRules"
            label-width="100px"
            style="max-width: 600px"
          >
            <el-form-item label="用户名">
              <el-input v-model="infoForm.username" disabled />
            </el-form-item>
            <el-form-item label="昵称" prop="nickname">
              <el-input v-model="infoForm.nickname" placeholder="请输入昵称" />
            </el-form-item>
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="infoForm.email" placeholder="请输入邮箱" />
            </el-form-item>
            <el-form-item label="手机号" prop="phone">
              <el-input v-model="infoForm.phone" placeholder="请输入手机号" />
            </el-form-item>
            <el-form-item label="头像">
              <el-upload
                class="avatar-uploader"
                :action="uploadUrl"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :on-error="handleAvatarError"
                :before-upload="beforeAvatarUpload"
                :headers="uploadHeaders"
                name="avatar"
                accept="image/*"
              >
                <img v-if="infoForm.avatar" :src="getAvatarUrl(infoForm.avatar)" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              </el-upload>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleUpdateInfo">保存</el-button>
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <!-- 修改密码 -->
        <el-tab-pane label="修改密码" name="password">
          <el-form
            ref="passwordFormRef"
            :model="passwordForm"
            :rules="passwordRules"
            label-width="100px"
            style="max-width: 600px"
          >
            <el-form-item label="原密码" prop="old_password">
              <el-input
                v-model="passwordForm.old_password"
                type="password"
                placeholder="请输入原密码"
                show-password
                @keyup.enter="handleChangePassword"
              />
            </el-form-item>
            <el-form-item label="新密码" prop="password">
              <el-input
                v-model="passwordForm.password"
                type="password"
                placeholder="请输入新密码（至少8位，包含大小写字母、数字和特殊字符）"
                show-password
                @input="checkPasswordStrength"
                @keyup.enter="handleChangePassword"
              />
              <div v-if="passwordForm.password" class="password-hints">
                <div class="password-strength">
                  <span class="strength-label">密码强度：</span>
                  <el-tag :type="passwordStrength.type" size="small">{{ passwordStrength.text }}</el-tag>
                </div>
                <div class="password-requirements">
                  <div class="requirement-item" :class="{ valid: passwordChecks.length >= 8 }">
                    <el-icon><Check v-if="passwordChecks.length >= 8" /><Close v-else /></el-icon>
                    <span>至少8个字符</span>
                  </div>
                  <div class="requirement-item" :class="{ valid: passwordChecks.hasLower }">
                    <el-icon><Check v-if="passwordChecks.hasLower" /><Close v-else /></el-icon>
                    <span>包含小写字母</span>
                  </div>
                  <div class="requirement-item" :class="{ valid: passwordChecks.hasUpper }">
                    <el-icon><Check v-if="passwordChecks.hasUpper" /><Close v-else /></el-icon>
                    <span>包含大写字母</span>
                  </div>
                  <div class="requirement-item" :class="{ valid: passwordChecks.hasNumber }">
                    <el-icon><Check v-if="passwordChecks.hasNumber" /><Close v-else /></el-icon>
                    <span>包含数字</span>
                  </div>
                  <div class="requirement-item" :class="{ valid: passwordChecks.hasSpecial }">
                    <el-icon><Check v-if="passwordChecks.hasSpecial" /><Close v-else /></el-icon>
                    <span>包含特殊字符</span>
                  </div>
                </div>
              </div>
            </el-form-item>
            <el-form-item label="确认密码" prop="password_confirmation">
              <el-input
                v-model="passwordForm.password_confirmation"
                type="password"
                placeholder="请再次输入新密码"
                show-password
                @keyup.enter="handleChangePassword"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleChangePassword" :loading="passwordChanging">修改密码</el-button>
              <el-button @click="resetPasswordForm">重置</el-button>
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Check, Close } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { useUserStore } from '@/stores/user'

const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const activeTab = ref('info')
const infoFormRef = ref(null)
const passwordFormRef = ref(null)
const passwordChanging = ref(false)

const infoForm = reactive({
  username: '',
  nickname: '',
  email: '',
  phone: '',
  avatar: '',
})

const passwordForm = reactive({
  old_password: '',
  password: '',
  password_confirmation: '',
})

const passwordChecks = reactive({
  length: 0,
  hasLower: false,
  hasUpper: false,
  hasNumber: false,
  hasSpecial: false,
})

const passwordStrength = computed(() => {
  const { length, hasLower, hasUpper, hasNumber, hasSpecial } = passwordChecks
  const score = [length >= 8, hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length
  
  if (score === 5) {
    return { type: 'success', text: '非常强' }
  } else if (score === 4) {
    return { type: 'success', text: '强' }
  } else if (score === 3) {
    return { type: 'warning', text: '中等' }
  } else if (score === 2) {
    return { type: 'warning', text: '较弱' }
  } else if (score === 1) {
    return { type: 'danger', text: '弱' }
  } else {
    return { type: 'info', text: '未评估' }
  }
})

const infoRules = {
  nickname: [
    { max: 50, message: '昵称长度不能超过50个字符', trigger: 'blur' },
  ],
  email: [
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' },
  ],
  phone: [
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
  ],
}

// 密码验证规则
const validatePassword = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请输入新密码'))
    return
  }
  
  if (value.length < 8) {
    callback(new Error('密码长度不能少于8位'))
    return
  }
  
  if (value.length > 100) {
    callback(new Error('密码长度不能超过100个字符'))
    return
  }
  
  // 检查是否包含小写字母
  if (!/[a-z]/.test(value)) {
    callback(new Error('密码必须包含至少一个小写字母'))
    return
  }
  
  // 检查是否包含大写字母
  if (!/[A-Z]/.test(value)) {
    callback(new Error('密码必须包含至少一个大写字母'))
    return
  }
  
  // 检查是否包含数字
  if (!/[0-9]/.test(value)) {
    callback(new Error('密码必须包含至少一个数字'))
    return
  }
  
  // 检查是否包含特殊字符
  if (!/[^a-zA-Z0-9]/.test(value)) {
    callback(new Error('密码必须包含至少一个特殊字符'))
    return
  }
  
  // 检查是否包含常见弱密码模式
  const weakPatterns = [
    /12345/,
    /password/i,
    /admin/i,
    /qwerty/i,
    /abc123/i,
  ]
  
  for (const pattern of weakPatterns) {
    if (pattern.test(value)) {
      callback(new Error('密码不能包含常见的弱密码模式'))
      return
    }
  }
  
  callback()
}

const passwordRules = {
  old_password: [
    { required: true, message: '请输入原密码', trigger: 'blur' },
    { max: 255, message: '密码长度不能超过255个字符', trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入新密码', trigger: 'blur' },
    { validator: validatePassword, trigger: 'blur' },
  ],
  password_confirmation: [
    { required: true, message: '请确认新密码', trigger: 'blur' },
    {
      validator: (rule, value, callback) => {
        if (!value) {
          callback(new Error('请确认新密码'))
          return
        }
        if (value !== passwordForm.password) {
          callback(new Error('两次输入的密码不一致'))
        } else {
          callback()
        }
      },
      trigger: 'blur',
    },
  ],
}

// 检查密码强度
const checkPasswordStrength = () => {
  const password = passwordForm.password
  passwordChecks.length = password.length
  passwordChecks.hasLower = /[a-z]/.test(password)
  passwordChecks.hasUpper = /[A-Z]/.test(password)
  passwordChecks.hasNumber = /[0-9]/.test(password)
  passwordChecks.hasSpecial = /[^a-zA-Z0-9]/.test(password)
}

// 重置密码表单
const resetPasswordForm = () => {
  Object.assign(passwordForm, {
    old_password: '',
    password: '',
    password_confirmation: '',
  })
  Object.assign(passwordChecks, {
    length: 0,
    hasLower: false,
    hasUpper: false,
    hasNumber: false,
    hasSpecial: false,
  })
  if (passwordFormRef.value) {
    passwordFormRef.value.clearValidate()
  }
}

const uploadUrl = '/api/profile/avatar'
const uploadHeaders = {
  Authorization: `Bearer ${userStore.token}`,
}

// 加载用户信息
const loadUserInfo = async () => {
  try {
    const res = await request.get('/profile')
    if (res.code === 200) {
      Object.assign(infoForm, res.data)
    }
  } catch (error) {
    console.error('加载用户信息失败:', error)
  }
}

// 更新个人信息
const handleUpdateInfo = async () => {
  try {
    await infoFormRef.value.validate()
    const res = await request.put('/profile', infoForm)
    if (res.code === 200) {
      ElMessage.success('更新成功')
      await userStore.getUserInfo()
      loadUserInfo()
    }
  } catch (error) {
    if (error.errors) {
      ElMessage.error('验证失败，请检查输入')
    } else {
      ElMessage.error(error.message || '更新失败')
    }
  }
}

// 修改密码
const handleChangePassword = async () => {
  try {
    // 验证表单
    await passwordFormRef.value.validate()
    
    // 检查新密码是否与原密码相同
    if (passwordForm.password === passwordForm.old_password) {
      ElMessage.error('新密码不能与原密码相同')
      return
    }
    
    passwordChanging.value = true
    
    try {
      const res = await request.post('/profile/password', {
        old_password: passwordForm.old_password,
        password: passwordForm.password,
        password_confirmation: passwordForm.password_confirmation,
      })
      
      if (res.code === 200) {
        ElMessage.success('密码修改成功，请重新登录')
        // 清空表单
        resetPasswordForm()
        // 延迟跳转登录
        setTimeout(() => {
          userStore.logout()
        }, 1500)
      }
    } catch (error) {
      // 处理错误响应
      let errorMessage = '修改失败'
      
      if (error.response) {
        const { data } = error.response
        if (data && data.message) {
          errorMessage = data.message
        } else if (data && data.errors) {
          // Laravel 验证错误
          const firstError = Object.values(data.errors)[0]
          errorMessage = Array.isArray(firstError) ? firstError[0] : firstError
        }
      } else if (error.message) {
        errorMessage = error.message
      }
      
      ElMessage.error(errorMessage)
    } finally {
      passwordChanging.value = false
    }
  } catch (error) {
    // 表单验证失败
    if (error.errors) {
      const firstError = Object.values(error.errors)[0]
      ElMessage.error(Array.isArray(firstError) ? firstError[0] : '验证失败，请检查输入')
    } else {
      ElMessage.error(error.message || '验证失败，请检查输入')
    }
  }
}

// 头像上传成功
const handleAvatarSuccess = (response, file) => {
  try {
    console.log('头像上传响应:', response)
    
    // Element Plus upload 组件返回的响应格式
    // 由于使用原生 XMLHttpRequest，响应可能直接是服务器返回的 JSON
    let avatarUrl = null
    let message = '上传成功'
    
    // 处理响应数据
    if (response && typeof response === 'object') {
      // 标准格式：{ code: 200, message: '...', data: { avatar: '...' } }
  if (response.code === 200) {
        if (response.data) {
          avatarUrl = response.data.url || response.data.avatar
          message = response.message || message
        }
      }
    }
    
    if (avatarUrl) {
      // 直接保存原始URL，不添加时间戳（在显示时添加）
      infoForm.avatar = avatarUrl
      
      ElMessage.success(message)
      
      // 立即强制更新视图
      // 使用 nextTick 确保 DOM 更新
      setTimeout(() => {
        // 更新用户信息（异步，不阻塞 UI 更新）
        userStore.getUserInfo().then(() => {
          // 用户信息更新后，重新加载表单数据以确保同步
          loadUserInfo()
        }).catch(err => {
          console.error('更新用户信息失败:', err)
        })
      }, 100)
  } else {
      console.error('无法获取头像URL，响应:', response)
      ElMessage.error(response?.message || '上传失败：无法获取头像地址')
  }
  } catch (error) {
    console.error('处理头像上传响应失败:', error)
    ElMessage.error('上传失败：' + (error.message || '未知错误'))
  }
}

// 获取头像URL（添加时间戳避免缓存）
const getAvatarUrl = (url) => {
  if (!url) return ''
  
  // 清理URL，移除可能已存在的时间戳参数
  let cleanUrl = url
  // 移除 ?t= 或 &t= 参数
  cleanUrl = cleanUrl.replace(/[?&]t=\d+/g, '')
  // 如果移除后末尾是 &，也移除
  cleanUrl = cleanUrl.replace(/&$/, '')
  
  // 添加新的时间戳避免浏览器缓存
  const separator = cleanUrl.includes('?') ? '&' : '?'
  return `${cleanUrl}${separator}t=${Date.now()}`
}

// 头像上传前验证
const beforeAvatarUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!')
    return false
  }
  return true
}

// 头像上传失败
const handleAvatarError = (error, file) => {
  console.error('头像上传失败:', error, file)
  ElMessage.error('头像上传失败，请重试')
}

// 处理标签页切换
const handleTabChange = (tabName) => {
  // 只在URL参数与当前标签不一致时更新URL
  const currentTab = route.query.tab
  if (tabName === 'password' && currentTab !== 'password') {
    router.replace({ path: '/profile', query: { tab: 'password' } })
  } else if (tabName === 'info' && currentTab) {
    router.replace({ path: '/profile' })
  }
}

// 根据路由查询参数设置活动标签页
const setActiveTabFromRoute = () => {
  const tab = route.query.tab
  if (tab === 'password') {
    activeTab.value = 'password'
  } else {
    activeTab.value = 'info'
  }
}

// 监听路由变化（用于浏览器前进后退或外部导航）
watch(() => route.query.tab, (newTab) => {
  // 只在标签页实际需要改变时更新
  if (newTab === 'password' && activeTab.value !== 'password') {
    activeTab.value = 'password'
  } else if ((newTab === 'info' || !newTab) && activeTab.value !== 'info') {
    activeTab.value = 'info'
  }
})

onMounted(() => {
  loadUserInfo()
  setActiveTabFromRoute()
})
</script>

<style scoped lang="scss">
.profile-container {
  // padding 由 app-container 统一管理
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.avatar-uploader {
  :deep(.el-upload) {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);

    &:hover {
      border-color: var(--el-color-primary);
    }
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
  }

    .avatar {
    width: 100px;
    height: 100px;
    display: block;
  }
}

.password-hints {
  margin-top: 8px;
  padding: 12px;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
  font-size: 12px;
}

.password-strength {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  
  .strength-label {
    color: var(--el-text-color-regular);
  }
}

.password-requirements {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.requirement-item {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--el-text-color-secondary);
  transition: color 0.3s;
  
  .el-icon {
    font-size: 14px;
  }
  
  &.valid {
    color: var(--el-color-success);
  }
  
  &:not(.valid) .el-icon {
    color: var(--el-color-danger);
  }
}
</style>

